﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.ModFlow.Domain.FileLayer;

using HA.ModFlow.Infrastructure;

namespace HA.ModFlow.Domain.DomainLayer
{
    [Serializable]
    public class BCFData : FlowDataBase
    {

        public BCFData(InnerFlowV2 parent)
            : base(parent)
        {



            this.InitGridData();



        }

        [field: NonSerialized]
        public event EventHandler BCFDataChanged;

        public void OnBCFDataChanged()
        {
            if (this.BCFDataChanged != null)
                this.BCFDataChanged(null, null);
        }

        List<BCFLayer> _layers = new List<BCFLayer>();

        public List<BCFLayer> Layers
        {
            get { return _layers; }
            set { _layers = value; }
        }


        CellCenterDataSet3d _transmissivity;
        /// <summary>
        /// 渗透率，只在为承压层，或者可转化层且渗透率始终为常量时需要，layertype 0 2
        /// </summary>
        public CellCenterDataSet3d Transmissivity
        {
            get { return _transmissivity; }
            set { _transmissivity = value; }
        }



        CellCenterDataSet3d _primaryStorage;


        /// <summary>
        /// 当至少存在一个tansient层时，需要此数据
        /// </summary>
        public CellCenterDataSet3d PrimaryStorage
        {
            get { return _primaryStorage; }
            set { _primaryStorage = value; }
        }



        CellCenterDataSet3d _secondaryStorage;

        /// <summary>
        /// 至少存在一个瞬时周期，且层类型为2或者3,只在承压，非承压可转换时可用
        /// </summary>
        public CellCenterDataSet3d SecondaryStorage
        {
            get { return _secondaryStorage; }
            set { _secondaryStorage = value; }
        }


        CellCenterDataSet3d _leakance;


        /// <summary>
        /// 垂直传到系数除以上下两层的厚度，因为最后一层的底部没有图层了，所以最后一层的这个值是没有必要设置的
        /// </summary>
        public CellCenterDataSet3d Leakance
        {
            get { return _leakance; }
            set { _leakance = value; }
        }



        int _IBCFCB = 0;

        /// <summary>
        /// 是否输出cell by cell term ,<0 输出到指定的UNIT >0 输出到lst文件
        /// </summary>
        public int IBCFCB
        {
            get { return _IBCFCB; }
            set { _IBCFCB = value; }
        }

        public void OnIboundsChanged(List<int[,]> iBound)
        {
            if (this._leakance != null)
                this._leakance.SetIBounds(iBound);
            if (this._primaryStorage != null)
                this._primaryStorage.SetIBounds(iBound);
            if (this._secondaryStorage != null)
                this._secondaryStorage.SetIBounds(iBound);
            if (this._transmissivity != null)
                this._transmissivity.SetIBounds(iBound);
        }


        public PBlockCenteredFlow ToBCFPack()
        {



            int layerNum = this._layers.Count;
            PBlockCenteredFlow pcf = new PBlockCenteredFlow(layerNum);



            pcf.IsHaveTransient = this.Parent.IsHaveTransient;



            pcf.HDRY = this.Parent.HDRY;
            pcf.IWDFLG = (this.Parent.CanWet) ? 1 : 0;
            pcf.WETFCT = this.Parent.WETFCT;
            pcf.IWETIT = this.Parent.IWETIT;
            pcf.IHDWET = this.Parent.IHDWET;


            //设置对应的ds属性

            this.PrimaryStorage.GetAllGridData(pcf.Sf1);

            this.SecondaryStorage.GetAllGridData(pcf.Sf2);

            this.Parent.WetDry.GetAllGridData(pcf.WETDRY);

            this.Parent.Hk.GetAllGridData(pcf.HY);

            this.Transmissivity.GetAllGridData(pcf.Tran);


            this.Leakance.GetAllGridData(pcf.Vcont);



            int i = 0;
            foreach (BCFLayer layer in this._layers)
            {
                switch (layer.LayerType)
                {
                    case BCFLAYERTYPE.CONFINED:
                        pcf.Ltype[i] = 0;
                        break;
                    case BCFLAYERTYPE.NOCONFINED:
                        pcf.Ltype[i] = 1;
                        break;
                    case BCFLAYERTYPE.TRANSMISSITYCONSTANT:
                        pcf.Ltype[i] = 2;
                        break;
                    case BCFLAYERTYPE.TRANSMISSITYVARY:
                        pcf.Ltype[i] = 3;
                        break;
                }

                pcf.TRPY[i] = layer.TRPY;
                pcf.LAYCON[i] = layer.LAYAVG;



                i++;
            }

            return pcf;


        }
        public object Clone()
        {
            BCFData data = new BCFData(new InnerFlowV2(new GridData(new GridConfig())));
            data = (BCFData)this.MemberwiseClone();
            data.Parent = new InnerFlowV2(new GridData(new GridConfig()));//
            data.Parent = (InnerFlowV2)this.Parent.Clone();
            data.Layers = new List<BCFLayer>();
            foreach (BCFLayer item in this.Layers)
            {
                data.Layers.Add((BCFLayer)item.Clone());
            }
            return data;
        }

        public BCFData CloneWithoutDataset()
        {
            BCFData data = (BCFData)this.MemberwiseClone();
            data.Layers = new List<BCFLayer>();
            foreach (BCFLayer item in this.Layers)
            {
                data.Layers.Add((BCFLayer)item.Clone());
            }
            return data;
        }


        protected void InitGridData()
        {
            double[, ,] transmissivity = new double[this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount, this.Parent.GridData.LayersCount];
            this.Transmissivity = new CellCenterDataSet3d(transmissivity, this.Parent.GridData.WaterGrid.GetIBounds());
            this.Transmissivity.Label = "Transmissivity";

            double[, ,] primaryStorage = new double[this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount, this.Parent.GridData.LayersCount];
            this.PrimaryStorage = new CellCenterDataSet3d(primaryStorage, this.Parent.GridData.WaterGrid.GetIBounds());
            this.PrimaryStorage.Label = "PrimaryStorage";

            double[, ,] secondaryStorage = new double[this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount, this.Parent.GridData.LayersCount];
            this.SecondaryStorage = new CellCenterDataSet3d(secondaryStorage, this.Parent.GridData.WaterGrid.GetIBounds());
            this.SecondaryStorage.Label = "SecondaryStorage";

            double[, ,] leakance = new double[this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount, this.Parent.GridData.LayersCount];
            this.Leakance = new CellCenterDataSet3d(leakance, this.Parent.GridData.WaterGrid.GetIBounds());
            this.Leakance.Label = "Leakance";
            this.Leakance.ConstantData(3);




            this.Layers.Clear();

            for (int i = 0; i < this.Parent.GridData.LayersCount; i++)
            {
                BCFLayer layer = new BCFLayer(this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount);

                this.Layers.Add(layer);

            }



        }

    }
}
